package com.wanjia.bpsapi.controller;


import com.wanjia.bpsapi.annotation.LoginToken;
import com.wanjia.bpsapi.exception.AddDataException;
import com.wanjia.bpsapi.exception.ControllerException;
import com.wanjia.bpsapi.exception.UpdateException;
import com.wanjia.bpsapi.mapper.DistanceMapper;
import com.wanjia.bpsapi.pojo.dto.DistanceDto;
import com.wanjia.bpsapi.pojo.entity.Distance;
import com.wanjia.bpsapi.pojo.entity.WjSupplier;
import com.wanjia.bpsapi.pojo.entity.WjUser;
import com.wanjia.bpsapi.pojo.model.JsonResult;
import com.wanjia.bpsapi.service.IDistanceService;
import com.wanjia.bpsapi.service.IMapService;
import com.wanjia.bpsapi.service.IWjSupplierService;
import com.wanjia.bpsapi.service.IWjUserService;
import com.wanjia.bpsapi.util.JsonResultUtil;
import com.wanjia.bpsapi.util.PageUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
@Tag(name = "距离控制接口")
public class DistanceController extends BaseController {

    @Autowired
    IWjSupplierService iWjSupplierService;

    @Autowired
    IWjUserService iWjUserService;

    @Autowired
    IMapService mapService;

    @Autowired
    IDistanceService distanceService;

    @Autowired
    DistanceMapper distanceMapper;

    @PostMapping("/distance")
    @Operation(summary = "预留自动算距离接口")
    public JsonResult AutoDistance(int uid) {
        List<WjSupplier> list = iWjSupplierService.list();
        List<String> locationList = list.stream().map(WjSupplier::getLocation).collect(Collectors.toList());
        List<Integer> baseIdList = list.stream().map(WjSupplier::getUid).collect(Collectors.toList());
        String location = iWjUserService.getUser(uid);
        List<Double> distances = new ArrayList<>(); //测算基地到商务的距离
        for (String s : locationList) {
            distances.add(mapService.distance(s, location));
            log.debug("{} -> {}", location, s);
        }
        Map<Object, Object> map = baseIdList.stream().collect(Collectors.toMap(key -> key, key -> distances.get(baseIdList.indexOf(key))));

        return JsonResultUtil.success(distances);
    }


    @PostMapping("/distance/input")
    @Operation(summary = "手动填写距离接口")
    @Parameter(in = ParameterIn.HEADER, name = "token")
    @LoginToken
    public JsonResult addDistance(@RequestBody Distance distance) {
        Long baseId = distance.getBaseId();
        Long clientId = distance.getClientId();
        Distance dis = distanceService.getDistance(baseId, clientId);
        if (dis != null) {
            throw new ControllerException("已经有距离，不能添加");
        }
        if (distance.getDistance() == null) {
            try {
                distance.setDistance(tryCalculateDistance(baseId, clientId));
            } catch (Exception e) {
                log.warn("自动计算路线失败", e);
            }
        }
        boolean save = distanceService.save(distance);
        if (save == false) {
            throw new AddDataException("新增数据发生错误");
        }
        return new JsonResult(OK);
    }

    private Double tryCalculateDistance(Long baseId, Long clientId) {
        WjSupplier supplier = iWjSupplierService.getById(baseId);
        if (supplier == null) {
            throw new ControllerException("无效的供应商id");
        }
        WjUser user = iWjUserService.getById(clientId);
        if (user == null) {
            throw new ControllerException("无效的客户id");
        }

        String supplierLocation = mapService.location(supplier.getSupplierAddress());
        if (supplierLocation == null) {
            throw new ControllerException("供应商经纬度检索失败");
        }

        String userLocation = mapService.location(user.getAddres());
        if (userLocation == null) {
            throw new ControllerException("客户经纬度检索失败");
        }

        Double distance = mapService.distance(supplierLocation, userLocation);
        if (distance == null) {
            throw new ControllerException("规划路线计算失败");
        }

        return distance / 1000;
    }

    @GetMapping("/distance")
    @Operation(summary = "获取距离接口")
    @Parameter(in = ParameterIn.HEADER, name = "token")
    @LoginToken
    public JsonResult<Object> getDistance(Long baseId, Long clientId, Integer pageNo, Integer pageSize) {
        List<DistanceDto> data = distanceService.getlist(baseId, clientId, pageNo, pageSize);
        Long total = distanceService.countlist(baseId, clientId);
        return new JsonResult<>(OK, PageUtil.page(pageNo, pageSize, total, data));
    }

    @PutMapping("/distance")
    @Operation(summary = "更新距离接口")
    @Parameter(in = ParameterIn.HEADER, name = "token")
    @LoginToken
    public JsonResult updateDistance(@RequestBody Distance distance) {
        int i = distanceService.updateDis(distance);
        if (i != 1) {
            throw new UpdateException("更新数据发生错误");
        }
        return new JsonResult(OK);
    }


    @PostMapping("/distance/calculate")
    @Operation(summary = "自动计算距离接口")
    @Parameter(in = ParameterIn.HEADER, name = "token")
    @LoginToken
    public JsonResult<Double> addDistance(Long baseId, Long clientId) {
        return JsonResultUtil.success(tryCalculateDistance(baseId, clientId));
    }

}
